#include "Star.hh"
#include "Galaxy.hh"
#include "../Geom/Vector.hh"
#include "../Exception.hh"
#include <boost/nondet_random.hpp>
#include <boost/random.hpp>

using namespace boost;
using namespace Geom;
using namespace World;

spStar Star::construct(u8 id, spGalaxy galaxy) {
    if (!galaxy)
        throw NullPointerException();

    random_device rng("/dev/urandom");
    uniform_real< f8 > rangePos(-GALAXY_SIZE, +GALAXY_SIZE);
    uniform_smallint< u1 > rangeNum(0, 10);
    variate_generator<
      random_device&,
      uniform_real< f8 >
    > randomPos(rng, rangePos);
    variate_generator<
      random_device&,
      uniform_smallint< u1 >
    > randomNum(rng, rangeNum);
    spStar star(new Star(id, Vector< f8 >(randomPos(), randomPos()), galaxy));
    u1 numPlanets = randomNum();

    for (u1 i = 0; i < numPlanets; ++i)
        star->planets.insert(i, Planet::construct(i, star));

    return star;
}

Star::Star(u8 id, Vector< f8 > const& position, spGalaxy galaxy):
    id(id),
    galaxy(galaxy),
    planets(),
    position(position) {}

void Star::next_turn() {
    for (
      PlanetMap::iterator i = planets.begin();
      i != planets.end();
      ++i
    ) {
        (*i)->next_turn();
    }
}

spPlanet Star::get_planet(u1 distance) const {
    QMutexLocker locker(&lock);
    spPlanet result = planets.value(distance);
    return result;
}

Star::PlanetMap Star::get_planets() const {
    QMutexLocker locker(&lock);
    PlanetMap result = planets;
    return result;
}
